package com.mySchool.aop;

import com.google.gson.*;
import com.mySchool.anno.SysLog;
import com.mySchool.entity.*;
import com.mySchool.entity.PO.OperateLogPO;
import com.mySchool.entity.bo.*;
import com.mySchool.mapper.SysLogMapper;
import lombok.extern.slf4j.*;
import org.aspectj.lang.*;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.stereotype.*;

import java.lang.reflect.*;
import java.time.LocalDateTime;
import java.util.*;

/**
* @author : Hinton
* @时间 : 2024/12/6 下午11:04
*/
@Aspect
@Component
@Slf4j
public class SysLogAspect {

    @Autowired
    private SysLogMapper sysLogMapper;

    /*
    @Pointcut()
    public void logPointCut() {}

    */

    /**
     * 这里我们使用注解的形式
     * <p>
     * 可以通过切点表达式直接指定需要拦截的package,需要拦截的class 以及 method
     * <p>
     * 切点表达式:   execution(...)
     * <p>
     * execution(public * *(..)) 任意的公共方法
     * <p>
     * execution（* set*（..）） 以set开头的所有的方法
     * <p>
     * execution（* com.LoggerApply.*（..））com.LoggerApply这个类里的所有的方法
     * <p>
     * execution（* com.annotation.*.*（..））com.annotation包下的所有的类的所有的方法
     * <p>
     * execution（* com.annotation..*.*（..））com.annotation包及子包下所有的类的所有的方法
     * <p>
     * execution(* com.annotation..*.*(String,?,Long)) com.annotation包及子包下所有的类的有三个参数，第一个参数为String类型，第二个参数为任意类型，第三个参数为Long类型的方法
     * <p>
     * execution(@annotation(com.lingyejun.annotation.Lingyejun))
    */
    @Around("@annotation(com.mySchool.anno.SysLog)")
    public Result<Object>  around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 计算运行时间
        long startTime = System.currentTimeMillis();

        // 执行被拦截的方法, 对原始操作的调用
        Object result = joinPoint.proceed();

        // 当前时间
        long endTime = System.currentTimeMillis();
        // 耗时
        long costTime = endTime - startTime;

        // 构建日志对象
        OperateLogPO operateLog = new OperateLogPO();
        // 需要实现 getCurrentUserId 方法
        operateLog.setOperateEmpId(getCurrentUserId());
        operateLog.setOperateTime(LocalDateTime.now());
        operateLog.setClassName(joinPoint.getTarget().getClass().getName());
        operateLog.setMethodName(joinPoint.getSignature().getName());
        operateLog.setMethodParams(Arrays.toString(joinPoint.getArgs()));
        operateLog.setReturnValue(result.toString());
        operateLog.setCostTime(costTime);


        log.info("操作日志：{}", operateLog);
        sysLogMapper.insert(operateLog);

        return Result.success(result);
    }

    // 获取当前用户ID
    private int getCurrentUserId() {
        // TODO: 从认证信息中获取当前登录用户的ID

        return 1;
    }

}
